#include <iostream>
#include "Log.h"
#include "std_def.h"
#include "neuron.h"
#include "adaptneuron.h"
#include "sigma_function.h"
#include "math.h"

using namespace std;

#define CYCLE_STUDY_COUNT_VAX 1000 /* min 300 - эксперементальным путем вычеслено*/

Log *plog = null;

static const int max_syn_count = 3;
static const int in_out_size = 3;
static double in_val_0 [] = {
	                                   0.5,
                                       0.1,
                                       0.2
                                     };
static double exp_out_0 = 0.3;

static double in_val_1[]  = {
	                                   0.2,
                                       0.3,
                                       0.4
                                     };
static double exp_out_1 = 0.25;
static const int max_signal_count = 2;

neuron   t_neuron;
adaptneuron t_adaptneuron;

double calcError(double fvalue, double svalue)
{
  return (svalue - fvalue) / fabs(fvalue);
}

int main()
{
  double error_val = 0.0;
  synapse _synapse;
  axon    _axon;
  plog = Log::getNewInstance();

  plog->setLogFile("/home/user/log/neuron_adapt.log");
  plog->open();
  plog->print("neuron_adapt->start()\n");

  t_neuron.setSynapseCount(max_syn_count);
  t_neuron.setActivTiling(0.5);
  t_neuron.init();
  t_neuron.setNeuronID(0);
  t_neuron.setCalcFunction( new sigma_function());


  for(int icount = 0; icount < max_syn_count; icount ++)
  {
    _synapse = t_neuron.getSynapse(icount);
    _synapse.setFSignalStudy(0, in_val_0[icount]);
    t_neuron.setSynapse(_synapse, icount);
  }

  t_neuron.calc_study();
  t_adaptneuron.setMaxError(0.01);
  t_adaptneuron.setCycleMaxCount(CYCLE_STUDY_COUNT_VAX);

  t_adaptneuron.setExpSignal(0, exp_out_0);
  (void)t_adaptneuron.start(t_neuron);

  plog->print("Cicle count max = %d\n", CYCLE_STUDY_COUNT_VAX);

  for(int icount = 0; icount < max_syn_count; icount ++)
  {
    _synapse = t_neuron.getSynapse(icount);
    _synapse.setFSignalStudy(1, in_val_1[icount]);
    t_neuron.setSynapse(_synapse, icount);
  }

  t_neuron.calc_study();
  t_adaptneuron.setExpSignal(1, exp_out_1);
  t_neuron = t_adaptneuron.start(t_neuron);



  plog->print("%%%%%%%%%% SIGNAL ID [%d] %%%%%%%%%%%%\n", 0);
  for(int insignal = 0; insignal < in_out_size; insignal ++)
    plog->print("in [%f] \n", in_val_0[insignal]);

  for(int icount = 0; icount < max_syn_count; icount ++)
  {
    _synapse = t_neuron.getSynapse(icount);
    _synapse.setFSignal(in_val_0[icount]);
    t_neuron.setSynapse(_synapse, icount);
  }
  t_neuron.calc();
  error_val = (t_neuron.getAxon().getFSignal() / exp_out_0) - 1;
  plog->print("after study signalid[%d] result = %f exp signal: %f calc error: %f\n", 0, t_neuron.getAxon().getFSignal(), exp_out_0, error_val);



  plog->print("%%%%%%%%%% SIGNAL ID [%d] %%%%%%%%%%%%\n", 1);
  for(int insignal = 0; insignal < in_out_size; insignal ++)
    plog->print("in [%f] \n", in_val_1[insignal]);

  for(int icount = 0; icount < max_syn_count; icount ++)
  {
    _synapse = t_neuron.getSynapse(icount);
    _synapse.setFSignal(in_val_1[icount]);
    t_neuron.setSynapse(_synapse, icount);
  }
  t_neuron.calc();
  error_val = (t_neuron.getAxon().getFSignal() / exp_out_1) - 1;
  plog->print("after study signalid[%d] result = %f exp signal: %f calc error: %f\n", 1, t_neuron.getAxon().getFSignal(), exp_out_1, error_val);




  for(int icount = 0; icount < max_syn_count; icount ++)
  {
    _synapse = t_neuron.getSynapse(icount);
    plog->print("synapse w [%f]\n", _synapse.getWeight());
  }

  plog->print("neuron_adapt->end()\n");
  return 0;
}
